package com.cmii.sjw.department.control.jsc.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.http.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cmii.sjw.department.control.jsc.mapper.ApiConfigMapper;
import com.cmii.sjw.department.control.jsc.mapper.CockpitMetricsTreeMapper;
import com.cmii.sjw.department.control.jsc.model.ApiConfig;
import com.cmii.sjw.department.control.jsc.model.entity.CockpitMetricsTree;
import com.cmii.sjw.department.control.jsc.model.params.DistrictParams;
import com.cmii.sjw.department.control.jsc.model.vo.CockpitMetricsVo;
import com.cmii.sjw.department.control.jsc.model.vo.EduCockpitHomeVo;
import com.cmii.sjw.department.control.jsc.model.vo.TzzbDetailedVo;
import com.cmii.sjw.department.control.jsc.service.EduCockpitService;
import com.cmii.sjw.department.control.jsc.util.Result;
import com.cmii.sjw.department.control.request.IRSUtil;
import com.cmii.sjw.department.control.request.bean.DataRequest;
import com.rw.tool.util.json.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author jfh
 * @Date 2025-05-12 周一 15:12
 * @Version 1.0
 */
@Slf4j
@Service
public class EduCockpitServiceImpl implements EduCockpitService {

    @Autowired
    private CockpitMetricsTreeMapper cockpitMetricsTreeMapper;

    @Autowired
    private MetricPermissionService permissionService;

    @Autowired
    private ApiConfigMapper apiConfigMapper;

    /**
     * 质量体系
     * @return 质量体系数据
     */
    @Override
    public Result<EduCockpitHomeVo> zltx() {
        EduCockpitHomeVo zltxVo = new EduCockpitHomeVo();
        try {
            // 定义父节点ID数组
            Long[] kpiParentId = {28277L};
            Long[] tzzbParentIds = {18482L, 18483L, 18485L, 18486L, 18487L, 28363L, 28366L};
            Long[] dksjParentId = {28319L};

            // 查询KPI信息
            List<CockpitMetricsVo> kpiVos = queryAndConvert(kpiParentId);
            zltxVo.setKpiDetailed(kpiVos);

            // 查询体征指标信息
            List<CockpitMetricsVo> vos = queryAndConvert(tzzbParentIds);
            Map<String, List<CockpitMetricsVo>> tzzbDetailedMap = vos.stream()
                    .collect(Collectors.groupingBy(
                            CockpitMetricsVo::getDescription,
                            Collectors.toList()
                    ));
            List<TzzbDetailedVo> tzzbDetailed = tzzbDetailedMap.entrySet().stream()
                    .map(entry -> {
                        TzzbDetailedVo detailedVo = new TzzbDetailedVo();
                        detailedVo.setName(entry.getKey());
                        detailedVo.setChildren(entry.getValue());
                        detailedVo.setNum(entry.getValue().size());
                        return detailedVo;
                    })
                    .collect(Collectors.toList());
            zltxVo.setTzzbDetailed(tzzbDetailed);

            // 查询多跨事件信息
            List<CockpitMetricsVo> dksjVos = queryAndConvert(dksjParentId);
            zltxVo.setDksjDetailed(dksjVos);

            // 设置统计信息
            zltxVo.setKpiCount(kpiVos.size());
            zltxVo.setTzzbCount(vos.size());
            zltxVo.setDksjCount(dksjVos.size());
        } catch (Exception e) {
            log.error("查询质量体系数据失败", e);
            return Result.error("查询质量体系数据失败");
        }
        return Result.success(zltxVo);
    }

    /**
     * 服务发展
     * @return 服务发展数据
     */
    @Override
    public Result<EduCockpitHomeVo> fwfz() {
        EduCockpitHomeVo fwfzVo = new EduCockpitHomeVo();
        try {
            // 定义父节点ID数组
            Long[] kpiParentId = {28310L};
            Long[] tzzbIds = {18693L};
            Long[] tzzbParentIds = {18694L, 18695L, 18696L, 18697L, 18698L, 18699L};
            Long[] dksjParentId = {28323L};

            // 查询KPI信息
            List<CockpitMetricsVo> kpiVos = queryAndConvert(kpiParentId);
            fwfzVo.setKpiDetailed(kpiVos);

            // 查询多跨事件信息
            List<CockpitMetricsVo> dksjVos = queryAndConvert(dksjParentId);
            fwfzVo.setDksjDetailed(dksjVos);

            // 查询体征指标信息
            List<CockpitMetricsVo> list = queryAndConvert(tzzbIds);

            List<TzzbDetailedVo> tzzbDetailed = new ArrayList<>();
            list.forEach(item -> {
                TzzbDetailedVo tzzb = new TzzbDetailedVo();
                List<CockpitMetricsVo> vos = queryAndConvert(item.getId());
                if (!vos.isEmpty()) {
                    tzzb.setName(item.getIndicator());
                    tzzb.setChildren(vos);
                    tzzb.setNum(vos.size());
                    tzzbDetailed.add(tzzb);
                }
            });
            fwfzVo.setTzzbDetailed(tzzbDetailed);

            //计算num和是多少
            int totalNum = tzzbDetailed.stream().mapToInt(tzzb -> tzzb.getNum()).sum();

            // 设置统计信息
            fwfzVo.setKpiCount(kpiVos.size());
            fwfzVo.setTzzbCount(totalNum);
            fwfzVo.setDksjCount(dksjVos.size());
        } catch (Exception e) {
            log.error("查询服务发展数据失败", e);
            return Result.error("查询服务发展数据失败");

        }
        return Result.success(fwfzVo);
    }

    /**
     * 关键绩效指标
     * @return 列表
     */
    @Override
    public Result<List<CockpitMetricsVo>> gjjxzbKpi() {
        Long kpiParentId = 28375L;
        List<CockpitMetricsVo> kpiVos = queryAndConvert(kpiParentId);
        return Result.success(kpiVos);
    }

    /**
     * 人才培养
     * @return 列表
     */
    @Override
    public Result<EduCockpitHomeVo> rcpy() {
        EduCockpitHomeVo rcpyVo = new EduCockpitHomeVo();

        try {
            // 定义父节点ID数组
            Long[] kpiParentId = {28283L};
            Long[] tzzbIds = {17373L};
            Long[] tzzbParentIds = {17374L, 17375L, 17376L, 17377L};
            Long[] dksjParentId = {28320L};

            // 查询KPI信息
            List<CockpitMetricsVo> kpiVos = queryAndConvert(kpiParentId);
            rcpyVo.setKpiDetailed(kpiVos);

            // 查询多跨事件信息
            List<CockpitMetricsVo> dksjVos = queryAndConvert(dksjParentId);
            rcpyVo.setDksjDetailed(dksjVos);

            // 查询体征指标信息
            List<CockpitMetricsVo> list = queryAndConvert(tzzbIds);
            List<TzzbDetailedVo> tzzbDetailed = new ArrayList<>();
            list.forEach(item -> {
                TzzbDetailedVo tzzb = new TzzbDetailedVo();
                List<CockpitMetricsVo> vos = queryAndConvert(item.getId());
                if (!vos.isEmpty()) {
                    tzzb.setName(item.getIndicator());
                    tzzb.setChildren(vos);
                    tzzb.setNum(vos.size());
                    tzzbDetailed.add(tzzb);
                }
            });
            rcpyVo.setTzzbDetailed(tzzbDetailed);

            //计算num和是多少
            int totalNum = tzzbDetailed.stream().mapToInt(tzzb -> tzzb.getNum()).sum();

            // 设置统计信息
            rcpyVo.setKpiCount(kpiVos.size());
            rcpyVo.setTzzbCount(totalNum);
            rcpyVo.setDksjCount(dksjVos.size());
        } catch (Exception e) {
            log.error("查询人才培养数据失败", e);
            return Result.error("查询人才培养数据失败");
        }
        return Result.success(rcpyVo);
    }

    /**
     * 师资队伍
     * @return 列表
     */
    @Override
    public Result<EduCockpitHomeVo> szdw() {
        EduCockpitHomeVo szdwVo = new EduCockpitHomeVo();
        try {
            // 定义父节点ID数组
            Long[] kpiParentId = {28301L};
            Long[] tzzbIds = {15055L};
            Long[] tzzbParentIds = {15056L, 15057L, 15058L, 15059L};
            Long[] dksjParentId = {28321L};

            // 查询KPI信息
            List<CockpitMetricsVo> kpiVos = queryAndConvert(kpiParentId);
            szdwVo.setKpiDetailed(kpiVos);

            // 查询多跨事件信息
            List<CockpitMetricsVo> dksjVos = queryAndConvert(dksjParentId);
            szdwVo.setDksjDetailed(dksjVos);

            // 查询体征指标信息
            List<CockpitMetricsVo> list = queryAndConvert(tzzbIds);
            List<TzzbDetailedVo> tzzbDetailed = new ArrayList<>();
            list.forEach(item -> {
                TzzbDetailedVo tzzb = new TzzbDetailedVo();
                List<CockpitMetricsVo> vos = queryAndConvert(item.getId());
                if (!vos.isEmpty()) {
                    tzzb.setName(item.getIndicator());
                    tzzb.setChildren(vos);
                    tzzb.setNum(vos.size());
                    tzzbDetailed.add(tzzb);
                }
            });
            szdwVo.setTzzbDetailed(tzzbDetailed);

            //计算num和是多少
            int totalNum = tzzbDetailed.stream().mapToInt(tzzb -> tzzb.getNum()).sum();

            // 设置统计信息
            szdwVo.setKpiCount(kpiVos.size());
            szdwVo.setTzzbCount(totalNum);
            szdwVo.setDksjCount(dksjVos.size());

        } catch (Exception e) {
            log.error("查询师资队伍数据失败", e);
            return Result.error("查询师资队伍数据失败");
        }
        return Result.success(szdwVo);
    }

    /**
     * 学校质量
     * @return 列表
     */
    @Override
    public Result<EduCockpitHomeVo> xxzl() {
        EduCockpitHomeVo xxzlVo = new EduCockpitHomeVo();
        try {
            // 定义父节点ID数组
            Long[] kpiParentId = {28305L};
            Long[] tzzbIds = {26097L};
            Long[] tzzbParentIds = {26098L, 26099L, 26100L, 26101L, 26102L, 26103L};
            Long[] dksjParentId = {28322L};

            // 查询KPI信息
            List<CockpitMetricsVo> kpiVos = queryAndConvert(kpiParentId);
            xxzlVo.setKpiDetailed(kpiVos);

            // 查询多跨事件信息
            List<CockpitMetricsVo> dksjVos = queryAndConvert(dksjParentId);
            xxzlVo.setDksjDetailed(dksjVos);

            // 查询体征指标信息
            List<CockpitMetricsVo> list = queryAndConvert(tzzbIds);
            Map<String, TzzbDetailedVo> mergeMap = new LinkedHashMap<>();

            // 优化后的合并逻辑
            list.stream()
                    .filter(item -> !queryAndConvert(item.getId()).isEmpty())  // 过滤掉空子项
                    .forEach(item -> {
                        List<CockpitMetricsVo> children = queryAndConvert(item.getId())
                                .stream()
                                .flatMap(v -> queryAndConvert(v.getId()).stream()) // 扁平化处理二级子项
                                .collect(Collectors.toList());

                        if (!children.isEmpty()) {
                            mergeMap.compute(item.getIndicator(), (key, existing) -> {
                                if (existing == null) {
                                    TzzbDetailedVo newTzzb = new TzzbDetailedVo();
                                    newTzzb.setName(key);
                                    newTzzb.setChildren(children);
                                    newTzzb.setNum(children.size());
                                    return newTzzb;
                                }
                                existing.getChildren().addAll(children);
                                existing.setNum(existing.getNum() + children.size());
                                return existing;
                            });
                        }
                    });

            xxzlVo.setTzzbDetailed(new ArrayList<>(mergeMap.values()));


            //计算num和是多少
//            int totalNum = tzzbDetailed.stream().mapToInt(tzzb -> tzzb.getNum()).sum();
            int totalNum = xxzlVo.getTzzbDetailed().stream().mapToInt(tzzb -> tzzb.getNum()).sum();

            // 设置统计信息
            xxzlVo.setKpiCount(kpiVos.size());
            xxzlVo.setTzzbCount(totalNum);
            xxzlVo.setDksjCount(dksjVos.size());

        } catch (Exception e) {
            log.error("查询学校质量数据失败", e);
            return Result.error("查询学校质量数据失败");
        }
        return Result.success(xxzlVo);
    }

    @Override
    public Result<String> districtCockkpit(DistrictParams params) {
        log.info("districtCockkpit params: {}", params);

        // 参数校验
        if (params == null) {
            log.error("参数不能为空");
            return Result.error("参数不能为空");
        }

        if (StringUtils.isBlank(params.getDistrictCode()) && StringUtils.isBlank(params.getDistrictName())) {
            log.error("districtCode和districtName不能同时为空");
            return Result.error("districtCode和districtName不能同时为空");
        }

        // 构建查询条件
        LambdaQueryWrapper<ApiConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApiConfig::getApiName, "区县驾驶舱")
                .eq(ApiConfig::getStatus, 1);

        // 根据存在的参数添加查询条件
        if (StringUtils.isNotBlank(params.getDistrictCode())) {
            queryWrapper.eq(ApiConfig::getDistrictCode, params.getDistrictCode());
        }

        if (StringUtils.isNotBlank(params.getDistrictName())) {
            queryWrapper.eq(ApiConfig::getDistrictName, params.getDistrictName());
        }

        // 从数据库查询接口配置
        ApiConfig apiConfig = apiConfigMapper.selectOne(queryWrapper);

        if (apiConfig == null) {
            log.error("未找到区县接口配置，districtCode: {}，districtName: {}",
                    params.getDistrictCode(), params.getDistrictName());
            return Result.error("未找到区县接口配置");
        }

        String result = "";

        // 自定义参数放到 params
        Map<String, String> irsParams = new HashMap<>();
        irsParams.put("districtcode", apiConfig.getDistrictCode());

        // 外层分页参数传进去
        DataRequest request = new DataRequest(irsParams, params.getPageNum(), params.getPageSize());

        String body = JsonUtil.toJson(request);
        try {
            log.info("接口请求url：{}，body：{}，accessKey：{}，secretKey：{}", apiConfig.getUrl(), body, apiConfig.getAccessKey(), apiConfig.getSecretKey());
            result = sendPostRequest(apiConfig.getUrl(), body, apiConfig.getAccessKey(), apiConfig.getSecretKey()); // 内部调用 private 方法

        } catch (Exception e) {
            log.error("IRS接口调用失败", e);
            return Result.error("IRS接口调用失败");
        }
        return Result.success(result);
    }

    /**
     * 查询指定父节点ID下的所有子节点
     * @param parentId 父节点ID
     * @return 子节点列表
     */
    private List<CockpitMetricsVo> queryAndConvert(Long... parentId) {
        // 检查是否有用户权限
        Set<Long> allowedMetricIds = permissionService.getUserMetricIds(StpUtil.getLoginIdAsLong());

        //  查询指定父节点ID下的所有子节点
        List<CockpitMetricsTree> list = allowedMetricIds.isEmpty() ?
                Collections.emptyList() :
                cockpitMetricsTreeMapper.selectList(new LambdaQueryWrapper<CockpitMetricsTree>()
                        .eq(CockpitMetricsTree::getIsOnScreen, "1")
                        .in(CockpitMetricsTree::getParentId, parentId)
                        .in(CockpitMetricsTree::getId, allowedMetricIds));

        List<CockpitMetricsVo> vos = new ArrayList<>();
        list.forEach(item -> {
            CockpitMetricsVo vo = new CockpitMetricsVo();
            BeanUtils.copyProperties(item, vo);
            vos.add(vo);
        });
        return vos;
    }

//    private List<CockpitMetricsVo> queryAndConvert(Long parentId) {
//        List<CockpitMetricsTree> list = cockpitMetricsTreeMapper.selectList(
//                new LambdaQueryWrapper<CockpitMetricsTree>()
//                        .eq(CockpitMetricsTree::getIsOnScreen, "1")
//                        .in(CockpitMetricsTree::getParentId, parentId)
//        );
//        List<CockpitMetricsVo> vos = new ArrayList<>();
//        list.forEach(item -> {
//            CockpitMetricsVo vo = new CockpitMetricsVo();
//            BeanUtils.copyProperties(item, vo);
//            vos.add(vo);
//        });
//        return vos;
//    }


    /**
     * 发送POST请求
     * 这里发送的请求参数默认设置的是JSON格式的
     * 有一些接口的参数是XML格式的，
     * 有一些接口还带一些query参数，
     * 请注意区别调整，修改代码
     *
     * @param url  url
     * @param body 请求的body参数
     * @return 请求结果
     * @throws HttpException 请求的httpStatus不为200时会打印日志，抛出异常
     */
    private String sendPostRequest(String url, String body , String accessKey, String secretKey ) {
        // 获取token
        String token = IRSUtil.getToken(accessKey, secretKey);

        // 使用url构造请求
        HttpRequest request = HttpRequest.of(url);

        // 指定GET请求
        request.method(Method.POST);
        // 把获取的Token放入请求头中，以获得授权
        request.header(IRSUtil.TOKEN_HEADER, token);

        // 放入query参数
        request.body(body);
        // 设置请求格式，这里默认为json
        request.contentType(ContentType.JSON.getValue());

        // 调用该接口
        HttpResponse response = request.execute();
        // 如果http状态不为200，则报错，输出日志
        if (response.getStatus() != HttpStatus.HTTP_OK) {
            String errorMessage = "http response status error!" +
                    "method:POST, url:{}, status:{}, accessKey:{}, secretKey:{}, " +
                    "token:{}, requestBody:{}, responseBody:{}";
            log.error(errorMessage, url, response.getStatus(), accessKey, secretKey,
                    token, body, response.body());

            String exceptionMessage = "请求接口状态码错误！请联系技术人员，详情请查看日志";
            throw new HttpException(exceptionMessage);
        }

        // 返回请求结果
        return response.body();
    }

}